package qqclient.service;

import qqclient.utils.Utility;
import qqcommon.Message;
import qqcommon.MessageType;
import qqcommon.User;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author DCSGO
 * @version 1.0
 * 客户端用户相关服务
 * 登录 注册
 */
public class UserClientService {
    private final User user;
    private String serverName;
    private final int serverPort;
    private Socket socket;
    private final DateTimeFormatter dtf;

    public void sendFile() {
        Message message = new Message();
        message.setSender(user.getUserId());
        message.setMesType(MessageType.MESSAGE_FILE_MES);
        System.out.print("需要将文件发送给：");
        String receiverId = Utility.readString(50);
        message.setReceiver(receiverId);
        System.out.println("请输入要发送的文件的绝对路径(文件大小不能超过2GB)：");
        String filePath = Utility.readString(300);
        File file = new File(filePath);
        while (!file.exists()) {
            System.out.println("文件不存在！请重新输入文件绝对路径：");
            filePath = Utility.readString(300);
            file = new File(filePath);
        }
        System.out.println("请输入要将该文件保存到：");
        String receiverFilePath = Utility.readString(300);
        message.setDestFilePath(receiverFilePath);
        message.setFileName(file.getName());
        message.setFileLen((int) file.length());
        //读取文件
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(filePath);
            byte[] fileBytes = new byte[(int) file.length()];
            fis.read(fileBytes);
            message.setFileBytes(fileBytes);
        } catch (IOException e) {
            e.printStackTrace();
            message.setFileName(null);
            message.setFileLen(-1);
            message.setFileBytes(null);
            message.setMesType(MessageType.MESSAGE_FAIL_IN_SEND);
        } finally {
            message.setSendTime(dtf.format(LocalDateTime.now()));
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                oos.writeObject(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //向所有在线用户发送消息 除了发送者
    public void sendMessagesToAll() {
        //读取用户输入
        System.out.println("请输入要对大家伙发的消息：");
        String content = Utility.readString(300);
        //设置消息
        Message message = new Message();
        message.setMesType(MessageType.MESSAGE_TO_ALL_MES);
        message.setSender(user.getUserId());
        message.setReceiver("所有在线用户");
        message.setContent(content);
        //添加发送时间
        message.setSendTime(dtf.format(LocalDateTime.now()));
        //发送消息
        try {
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //向用户私聊
    public void sendMessage() {
        //读取用户输入
        System.out.print("\n请输入要私聊的用户名：");
        String receiver = Utility.readString(50);
        System.out.print("请输入要发送的消息：");
        String content = Utility.readString(300);
        //设置消息
        Message message = new Message();
        message.setMesType(MessageType.MESSAGE_COMM_MES);
        message.setSender(user.getUserId());
        message.setReceiver(receiver);
        message.setContent(content);
        //添加发送时间
        message.setSendTime(dtf.format(LocalDateTime.now()));
        //发送消息
        try {
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void exit() {
        //1.向服务端发送退出消息
        Message message = new Message();
        message.setSender(user.getUserId());
        message.setMesType(MessageType.MESSAGE_CLIENT_EXIT);
        try {
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //2.退出
        System.out.println("已退出系统...");
        System.exit(0);
    }

    public boolean checkUser(String id, String pwd) {
        boolean b = false;

        user.setUserId(id);
        user.setPasswd(pwd);
        //向服务端发送 user 让服务端判断是否有该 user 并接收服务端回传的消息
        try {
            socket = new Socket(serverName, serverPort);
            //向服务端发送 user
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(user);
            oos.flush();

            //接收服务端回传的消息
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Message message = (Message) ois.readObject();
            //有该 user 登录成功
            if (message.getMesType().equals(MessageType.MESSAGE_LOGIN_SUCCEED)) {
                //创建user 与服务端的连接
                ClientConnectServerThread thread = new ClientConnectServerThread(socket);
                thread.start();
                ManageClientConnectServerThread.add(id, thread);
                b = true;
            } else {
                //登录失败
                socket.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return b;
    }

    public void printOnlineUsers() {
        //1.向服务端发送 获取在线用户的消息
        Socket clientSocket = ManageClientConnectServerThread.get(user.getUserId()).getSocket();
        Message message = new Message();
        message.setMesType(MessageType.MESSAGE_GET_ONLINE_USERS);
        message.setSender(user.getUserId());
        try {
            ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //2.接收服务端回传的 在线用户信息(用户名之间用空格分隔)并输出显示
        //该部分在 ClientConnectServerThread 的 run 方法中实现
    }

    public UserClientService() {
        try {
            serverName = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        /*serverName = "47.113.198.9";*/
        serverPort = 9999;
        user = new User();
        dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 E HH:mm:ss");
    }

}
